<?php

namespace App\Models\OpenShop\InvestmentPromotion;

use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class OpenShopSignOrderLogModel extends BaseModel
{
    protected $table = 'open_shop_sign_order_logs';

    protected $fillable = [
        'orderId',
        'content',
        'type',
        'operatorName',
        'changes',
    ];

    const TYPE_ORDER_CREATED                  = 1;
    const TYPE_ORDER_EDITED                   = 2;
    const TYPE_SIGN_SMS_SENT                  = 3;
    const TYPE_ORDER_CLOSED                   = 4;
    const TYPE_ORDER_AUTO_CLOSED              = 5;
    const SEND_JOIN_SMS                       = 6;
    const SEND_ORDER_CONTRACT_CREATED         = 7;
    const SELECTION_DEVELOP_MANAGER           = 8;
    const SELECTION_SUBMIT_REPORT             = 9;
    const SELECTION_SUBMIT_DISCLOSURE         = 10;
    const MERCHANT_CONFIRMATION_REPORT        = 11;
    const UPDATED_SUBMIT_DISCLOSURE           = 12;
    const CONTRACT_EXCEPTION_HAPPEN           = 13;
    const CONTRACT_EXCEPTION_HANDLE           = 14;
    const UPLOAD_ORDER_PAY_PROOF              = 15;
    const UPDATE_SHOP_LOCATION                = 16;
    const UPDATE_SPACE_DESIGN                 = 17;
    const UPDATE_ENGINEERING_CONSTRUCTION     = 18;
    const UPDATE_SHOP_CHECK_ACCEPT            = 19;
    const ADD_COST_ORDER                      = 20;
    const UPDATE_COST_ORDER                   = 21;
    const REFUND_COST_ORDER                   = 22;
    const COMPLETE_COST_ORDER                 = 23;
    const CLOSE_COST_ORDER                    = 24;
    const ADD_SOFT_ORDER                      = 25;
    const UPDATE_SOFT_ORDER                   = 26;
    const REFUND_SOFT_ORDER                   = 27;
    const CLOSE_SOFT_ORDER                    = 29;
    const CONFIRM_COST_ORDER                  = 31;
    const REFUND_FIT                          = 32;
    const UPLOAD_FILE                         = 33;
    const COMPLETE_SOFT_ORDER                 = 34;
    const SEND_SOFT                           = 35;
    const UPDATE_MANAGER                      = 36;
    const UPDATE_START_BUSINESS               = 37;
    const UPDATE_REFRESH_MANUAL               = 38;
    const INVALID_USER_CONTRACT_WITH_SIGN     = 39;
    const INVALID_USER_CONTRACT_WITHOUT_SIGN  = 40;
    const INVALID_ORDER                       = 41;
    const INVALID_ORDER_CONTRACT_SIGN         = 42;
    const INVALID_ORDER_RE_SITE               = 43;
    const SKIP_STEP_DESIGN                    = 44;
    const SKIP_STEP_EQUIPMENT                 = 45;
    const SKIP_STEP_DECORATE                  = 46;
    const SKIP_STEP_UNBIND_FUNCTION_OPEN      = 47;
    const SKIP_STEP_UPDATE_SCHEDULED_TIME     = 48;
    const SKIP_STEP_UPDATE_PREPARATION_INFO   = 49;
    const SKIP_STEP_UPDATE_SITE_LOCATION      = 50;
    const SKIP_STEP_UPDATE_SITE_LOCATION_INFO = 51;
    const RENEW_ORDER_CONTRACT_SIGN           = 52;

    const TYPES = [
        self::TYPE_ORDER_CREATED                  => '创建开店订单',
        self::TYPE_ORDER_EDITED                   => '修改开店订单',
        self::TYPE_SIGN_SMS_SENT                  => '发送支付短信',
        self::TYPE_ORDER_CLOSED                   => '关闭开店订单',
        self::TYPE_ORDER_AUTO_CLOSED              => '自动关闭开店订单',
        self::SEND_JOIN_SMS                       => '发送加盟成功短信',
        self::SEND_ORDER_CONTRACT_CREATED         => '创建加盟合同',
        self::SELECTION_DEVELOP_MANAGER           => '指派开发顾问',
        self::SELECTION_SUBMIT_REPORT             => '提交选址报告',
        self::SELECTION_SUBMIT_DISCLOSURE         => '上传披露信息',
        self::MERCHANT_CONFIRMATION_REPORT        => '商家确认选址报告',
        self::UPDATED_SUBMIT_DISCLOSURE           => '修改披露信息',
        self::CONTRACT_EXCEPTION_HAPPEN           => '合同生成发生异常',
        self::CONTRACT_EXCEPTION_HANDLE           => '合同异常信息处理',
        self::UPLOAD_ORDER_PAY_PROOF              => '上传支付凭证',
        self::UPDATE_SHOP_LOCATION                => "修改选址报告",
        self::UPDATE_SPACE_DESIGN                 => "修改筹备信息(门店全套图)",
        self::UPDATE_ENGINEERING_CONSTRUCTION     => "修改筹备信息(工程营建)",
        self::UPDATE_SHOP_CHECK_ACCEPT            => "修改筹备信息(门店验收)",
        self::ADD_COST_ORDER                      => "设计订单-新增",
        self::UPDATE_COST_ORDER                   => "设计订单-编辑",
        self::REFUND_COST_ORDER                   => "设计订单-退款",
        self::COMPLETE_COST_ORDER                 => "设计订单-完成",
        self::CONFIRM_COST_ORDER                  => "设计师确认设计模块",
        self::CLOSE_COST_ORDER                    => "设计订单-关闭",
        self::ADD_SOFT_ORDER                      => "软装订单-新增",
        self::UPDATE_SOFT_ORDER                   => "软装订单-编辑",
        self::REFUND_SOFT_ORDER                   => "软装订单-退款",
        self::COMPLETE_SOFT_ORDER                 => "软装订单-完成",
        self::CLOSE_SOFT_ORDER                    => "软装订单-关闭",
        self::REFUND_FIT                          => "装修保证金退款",
        self::UPLOAD_FILE                         => "设计师上传整套图",
        self::SEND_SOFT                           => "软装订单-发货",
        self::UPDATE_MANAGER                      => "修改顾问",
        self::UPDATE_START_BUSINESS               => "修改开业报告",
        self::UPDATE_REFRESH_MANUAL               => "重置授权书",
        self::INVALID_USER_CONTRACT_WITH_SIGN     => "作废合同 (已签署)",
        self::INVALID_USER_CONTRACT_WITHOUT_SIGN  => "作废合同 (待签署)",
        self::INVALID_ORDER                       => "作废订单",
        self::INVALID_ORDER_CONTRACT_SIGN         => "作废合同签署",
        self::INVALID_ORDER_RE_SITE               => "选址变更",
        self::SKIP_STEP_DESIGN                    => "跳过设计流程",
        self::SKIP_STEP_EQUIPMENT                 => "跳过设备流程",
        self::SKIP_STEP_DECORATE                  => "跳过软装流程",
        self::SKIP_STEP_UNBIND_FUNCTION_OPEN      => "功能开通重置",
        self::SKIP_STEP_UPDATE_SCHEDULED_TIME     => "修改预计开业时间",
        self::SKIP_STEP_UPDATE_PREPARATION_INFO   => "修改筹备信息",
        self::SKIP_STEP_UPDATE_SITE_LOCATION      => "修改选址信息",
        self::SKIP_STEP_UPDATE_SITE_LOCATION_INFO => "修改选址说明",
        self::RENEW_ORDER_CONTRACT_SIGN           => "续签合同签署",
    ];

    /**
     * 日志写入
     *
     * @param int $orderId
     * @param int $type
     * @param string $operatorName
     * @param int $uid
     * @param mixed $changes
     */
    public static function logInsert(int $orderId, int $type, string $operatorName = "系统", int $uid = 0, ...$changes)
    {
        if (empty($changes)) {
            $changes = "";
        } else {
            if (count($changes) == 1 && is_string($changes[0])) {
                $changes = $changes[0];
            } else {
                $changes = collect($changes)->map(function (BaseModel $model) {
                    $manager = DB::connection()->getDoctrineSchemaManager();
                    $table   = $manager->listTableDetails($model->getTable());

                    return [
                        "description" => $table->getComment(),
                        "before"      => collect($model->getRawOriginal())
                            ->only(array_keys($model->getChanges()))
                            ->map(function ($v, $k) use ($table) {
                                return [
                                    "description" => $table->getColumn($k)->getComment(),
                                    "type"        => "string",
                                    "value"       => $v
                                ];
                            })->toArray(),
                        "after"       => collect($model->getChanges())->map(function ($v, $k) use ($table) {
                            return [
                                "description" => $table->getColumn($k)->getComment(),
                                "type"        => "string",
                                "value"       => $v
                            ];
                        })->toArray()
                    ];
                })->toJson(JSON_UNESCAPED_UNICODE);
            }
        }

        self::query()->insert([
            "orderId"      => $orderId,
            "type"         => $type,
            "content"      => self::TYPES[$type],
            "operatorName" => $operatorName,
            "createdAt"    => time(),
            "createdByUid" => $uid,
            "changes"      => $changes
        ]);
    }

    public static function getChangeContents(BaseModel $model)
    {
        $after  = $model->getChanges();
        $before = collect($model->getRawOriginal())
            ->only(array_keys($after))
            ->toArray();
        return json_encode([
            "before" => $before,
            "after"  => $after
        ], JSON_UNESCAPED_UNICODE);
    }

    public function getChangesAttribute()
    {
        $changes = $this->attributes['changes'] ?? '';
        return (string)$changes;
    }

    protected static function boot()
    {
        parent::boot();
        static::saving(function (OpenShopSignOrderLogModel $model) {
            $model->setAttribute('changes', (string)($model->attributes['changes'] ?? ''));
        });
    }

    /**
     * @param $orderId
     * @param $type
     * @return Builder|Model|object|null
     */
    public static function getInfoByOrderId($orderId, $type)
    {
        return OpenShopSignOrderLogModel::query()
                                        ->where('orderId', $orderId)
                                        ->where('type', $type)
                                        ->orderBy('id', 'desc')
                                        ->first();
    }
}
